package cn.antcore.kafka.builder;

import cn.antcore.kafka.ConsumerCallback;
import cn.antcore.kafka.annotation.ClientFail;
import cn.antcore.kafka.annotation.ClientInit;
import cn.antcore.kafka.annotation.ClientReceive;
import cn.antcore.kafka.annotation.ClientSuccess;
import cn.antcore.kafka.entity.ReceiveResult;
import cn.antcore.kafka.utils.BeanUtils;

import java.lang.reflect.Method;

/**
 * ConsumerCallback实现类
 *
 * Created By Hong on 2018/8/22
 **/
public class ConsumerCallbackImpl implements ConsumerCallback {

    protected Object target;
    /**
     * 全部方法
     */
    private Method[] methods;

    /**
     * 构造函数
     *
     * @param target 目标类
     */
    public ConsumerCallbackImpl(Object target) {
        this.target = target;
        this.methods = BeanUtils.getMethods(target.getClass());
    }

    @Override
    public void onInit() {
        Method method = BeanUtils.getMethodByAnnotation(methods, ClientInit.class);
        if (method != null) {
            BeanUtils.invokeMethod(target, method);
        }
    }

    @Override
    public void onReceive(ReceiveResult result) {
        Method method = BeanUtils.getMethodByAnnotation(methods, ClientReceive.class);
        if (method == null) {
            return;
        }
        if (BeanUtils.validParameterTypes(method, 1, result.getClass())) {
            BeanUtils.invokeMethod(target, method, result);
        } else {
            BeanUtils.invokeMethod(target, method);
        }
    }

    @Override
    public void onSuccess(Object key, Object body) {
        Method method = BeanUtils.getMethodByAnnotation(methods, ClientSuccess.class);
        if (method == null) {
            return;
        }
        if (BeanUtils.validParameterTypes(method, 2, key.getClass(), body.getClass())) {
            BeanUtils.invokeMethod(target, method, key, body);
        } else if (BeanUtils.validParameterTypes(method, 1, body.getClass())) {
            BeanUtils.invokeMethod(target, method, body);
        } else {
            BeanUtils.invokeMethod(target, method);
        }
    }

    @Override
    public void onFail(Exception e) {
        Method method = BeanUtils.getMethodByAnnotation(methods, ClientFail.class);
        if (method == null) {
            return;
        }
        if (BeanUtils.validParameterTypes(method, 1, e.getClass())) {
            BeanUtils.invokeMethod(target, method, e);
        } else {
            BeanUtils.invokeMethod(target, method);
        }
    }
}
